package main

import (
	"fmt"
	"net/http"
	"strconv"
)

type PageState struct {
	Counter int
	Next    int
}

templ Page(state PageState) {
	<!DOCTYPE html>
	<html>
		<head>
			<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.min.js"></script>
			<link rel="stylesheet" href="https://unpkg.com/missing.css@1.1.3/dist/missing.min.css"/>
			<title>Template Fragment Example</title>
		</head>
		<body>
			<h1>Template Fragment Example</h1>
			<p>
				This page demonstrates how to create and serve 
				<a href="https://htmx.org/essays/template-fragments/">template fragments</a>
				using <a href="https://templ.guide">templ</a> in Go.
			</p>
			<p>
				This is accomplished by using the "templ.Fragment" component, which lets you
				select areas to include in the output.
			</p>
			<p>
				Adapted from https://gist.github.com/benpate/f92b77ea9b3a8503541eb4b9eb515d8a
			</p>
			<!-- Here's the fragment.  We can target it by executing the "buttonOnly" template. -->
			@templ.Fragment("buttonOnly") {
				<button hx-get={ fmt.Sprintf("/?counter=%d&template=buttonOnly", state.Next) } hx-swap="outerHTML">
					This Button Has Been Clicked { state.Counter } Times
				</button>
			}
		</body>
	</html>
}

// handleRequest does the work to execute the template (or fragment) and serve the result.
// It's mostly boilerplate, so don't get hung up on it.
func handleRequest(w http.ResponseWriter, r *http.Request) {
	// Collect state info to pass to the template.
	var state PageState
	state.Counter, _ = strconv.Atoi(r.URL.Query().Get("counter"))
	state.Next = state.Counter + 1

	// If the template querystring paramater is set, render the pecific fragment.
	var opts []func(*templ.ComponentHandler)
	if templateName := r.URL.Query().Get("template"); templateName != "" {
		opts = append(opts, templ.WithFragments(templateName))
	}

	// Render the template or fragment and serve it.
	templ.Handler(Page(state), opts...).ServeHTTP(w, r)
}

func main() {
	// Handle the template.
	http.HandleFunc("/", handleRequest)

	// Start the server.
	fmt.Println("Server is running at http://localhost:8080")
	http.ListenAndServe("localhost:8080", nil)
}
